package P126_SelectThreadPool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

/**
 * @author xufy
 * @version 1.0
 * @description 选择合适的线程池
 **/
public class SelectThreadPool {

    //线程都有启动、运行、销毁过程，一个线程不能重复使用
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //newCachedThreadPool创建线程
        thread1();
        //使用newSingleThreadExecutor线程池
        thread2();


    }

    public static void thread1() throws InterruptedException, ExecutionException {
        //最大线程不超过 Integer最大值
        ExecutorService es = Executors.newCachedThreadPool();
        Future<String> future = es.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "hello world";
            }
        });
        System.out.println("返回值：" + future.get());
        es.shutdown();
    }

    public static void thread2() throws ExecutionException, InterruptedException {
        ExecutorService es = Executors.newSingleThreadExecutor();
        Future<String> future = es.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "hello world";
            }
        });
        System.out.println("返回值：" + future.get());
        es.shutdown();
    }
}

class ThreadPoolExecutor {

    //最小线程数
    private volatile int corePoolSize;
    //最大线程数
    private volatile int maximumPoolSize;
    //最大线程数量
    private final BlockingQueue<Runnable> workQueue;
    //线程最大生命期
    private volatile long keepAliveTime;
    //线程工厂，定义启动一个线程，名称、是否后台线程等
    private volatile ThreadFactory threadFactory;
    //拒绝任务处理器，超出线程数量、队列容量是程序处理方法
    private volatile RejectedExecutionHandler handler;

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
                maximumPoolSize <= 0 ||
                maximumPoolSize < corePoolSize ||
                keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
}